package com.example.nebula.service;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.nebula.dto.graph.GraphShowInfo;
import com.example.nebula.exception.GraphExecuteException;
import com.example.nebula.util.NebulaUtil;
import com.example.nebula.vo.AttributeVo;
import com.vesoft.nebula.client.graph.SessionPool;
import com.vesoft.nebula.client.graph.exception.AuthFailedException;
import com.vesoft.nebula.client.graph.exception.BindSpaceFailedException;
import com.vesoft.nebula.client.graph.exception.ClientServerIncompatibleException;
import com.vesoft.nebula.client.graph.exception.IOErrorException;
import com.vesoft.nebula.client.graph.net.Session;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 图数据库语句执行
 */
@Slf4j
@Service
public class GraphCommonService {

    @Autowired
    SessionPool sessionPool;

    public List executeJson(String gql, Class<?> voClass) {

        try {
            log.info("执行 executeJson 方法，gql={}", gql);

            final String data = sessionPool.executeJson(gql);
            log.info("执行 executeJson 方法，data={}", data);
            final JSONObject jsonObject = JSON.parseObject(data);
            // 查询语句异常分析, 根据 json 返回结果解析 error 节点信息
            final JSONObject error0 = jsonObject.getJSONArray("errors").getJSONObject(0);
            final Integer code = error0.getInteger("code");
            if (code != 0) {
                error0.put("gql",gql);
            }
            JSONArray results = JSONUtil.parseArray(jsonObject.get("results"));
            log.info("返回结果: {}", results);
            return JSONUtil.toList(results, voClass);
        } catch (Exception e) {
            log.error("executeJson ql[{}] error, msg [{}]", gql, e.getMessage());
            throw new GraphExecuteException("execute gql error, gql: " + gql, e);
        }   finally {
//            sessionPool.close();
        }
    }

    public String getVidType(String space) {
        List<AttributeVo> spaceList = executeJson(NebulaUtil.showAttributeInfo(GraphShowInfo.builder()
                        .attribute("space").attributeName(space).space(space).build())
                , AttributeVo.class);
        AttributeVo attributeVo = spaceList.get(0);
        if(attributeVo.getErrors()!=null && attributeVo.getErrors().getCode()!=0){
            throw new GraphExecuteException(attributeVo.getErrors().getMessage());
        }
        AttributeVo.DataBean dataBean = attributeVo.getData().get(0);
        return dataBean.getRow().get(6);
    }

    public com.alibaba.fastjson.JSONArray executeJson(String gql) throws GraphExecuteException {
//        Session session = sessionPool.borrow();
        try {

            final String data = sessionPool.executeJson(gql);
            log.info(data);
            final JSONObject jsonObject = JSON.parseObject(data);
            return jsonObject.getJSONArray("results");
        } catch ( Exception e) {
            log.error("executeJson ql[{}] error, msg [{}]", gql, e.getMessage());
//            throw new GraphExecuteException(-1,gql, e.getMessage());
            throw new GraphExecuteException("execute gql error, gql: " + gql, e);
        }finally {
//            session.release();
        }
    }

}
